package edu.hm.dako.EchoApplication.TCPMultiThreaded;


import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/*
 * Logging
 */
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.PropertyConfigurator;

import edu.hm.dako.EchoApplication.Basics.EchoPDU;

/**
 * Klasse TCPMultiThreadedEchoServer
 *  
 * @author Mandl
 *
 */
public class TCPMultiThreadedEchoServer extends Thread
{	 
		private static Log log = LogFactory.getLog(TCPMultiThreadedEchoServer.class);

		private static int serverPort = 50000;
		
		private static int numberOfWorkerThread = 0;
		
		// Verbindungstabelle: Hier werden alle aktiven Verbindungen zu Clients verwaltet
	    private static Map<String, Socket> connections = new ConcurrentHashMap<String, Socket>();
	 
	    // TCP-Socket des Servers (Listen-Socket)
	    private static ServerSocket serverSocket;
	    
		// Transportverbindung und Streams fuer einen Client
	    private Socket con;
		private ObjectOutputStream out;
		private ObjectInputStream in;
		private Thread runner;
		
		// Groesse des Empfangspuffers einer TCP-Verbindung in Byte
		private static final int receiveBufferSize = 300000;
	
		 static  TCPMultiThreadedEchoClientThread t[] = new TCPMultiThreadedEchoClientThread[numberOfWorkerThread]; 
		
	    /**
	     * Konstruktor
	     */
		public TCPMultiThreadedEchoServer(Socket incoming)
		{		
			 this.con = incoming;

			 // Ein- und Ausgabe-Objektstrom erzeugen
			 try {
		        out = new ObjectOutputStream(incoming.getOutputStream());
		        in = new ObjectInputStream(incoming.getInputStream());
		        
		        runner = new Thread(this);
		        runner.start();
		      }  
		      catch (Exception e) { 
		    	  //TODO
		      }
		}

   	    public void main (String args[])
   	    {
   	    	PropertyConfigurator.configureAndWatch("log4j.server.properties", 60 * 1000);
   	    	
   	    	// TCP-Serversocket registrieren
   	    	try {
   	    		serverSocket = new ServerSocket(serverPort);
   	    		System.out.println("TCPEchoServer wartet auf Clients...");
   	    	} catch (IOException e) { 
   	    	   log.debug("Exception bei der Socket-Erzeugung: " + e);
	           System.exit(9);
   	    	} 
   	    	
   	    	
   	    	while (true) {
   	    		try {
					con  = serverSocket.accept();
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
   	    		  /*			for(int i=0; i<=9; i++){
				    if(t[i]==null)
					{
					    (t[i] = new clientThread(clientSocket,t)).start();
					    break;
*/
				new TCPMultiThreadedEchoServer(con).run();
   	    	 }
   	    }
   	    
   	    /**
   	     * Worker-Thread-Methode fuer die Bearbeitung eines Clients
   	     */
   	    
   	  public void run()
   	  {
   	    try
   	    {
   	      while(true)
   	      {
   	        String rawPacket = in.readLine();

   	        if(rawPacket != null)
   	        {
   	          ProcessPacket(rawPacket);
   	        }
   	        else
   	        {
   	          ObjectInputStream clientSocket;
			clientSocket.close();
   	          sckClient = null;
   	          runner = null;
   	          break;
   	        }
   	      }
   	    }
   	    catch(IOException e)
   	    {
   	      //Error-Output
   	    }
   	  }

   	  private void ProcessPacket(String rawPacket)
   	  {
   	    System.out.println("Incoming Packet : " + rawPacket);
   	  }   
 }